package de.jtserver;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.backends.BackendService;
import com.google.appengine.api.backends.BackendServiceFactory;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.appengine.api.utils.SystemProperty;

import de.jtserver.model.JTalkScript;

@SuppressWarnings("serial")
public class Jtalk_serverServlet extends HttpServlet {

	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		Logger logger = Logger.getLogger("de.jtserver");
		logger.warning("GET!");

		UserService userService = UserServiceFactory.getUserService();

		boolean isDevelopment = (SystemProperty.environment.value() == SystemProperty.Environment.Value.Development);
		if (req.getUserPrincipal() != null || isDevelopment) {
			String owner = null;
			if (isDevelopment) {
				owner = "ich";
			} else {
				owner = req.getUserPrincipal().getName();
			}
			String jsfile = req.getParameter("file");
			if (jsfile != null && jsfile.equalsIgnoreCase("jtalk.js")) {
				String script = JScriptHelper.getScript(owner);
				resp.setContentType("application/x-javascript");
				resp.getWriter().println(script);
			}
		} else {
			resp.setContentType("application/x-javascript");
			resp.getWriter().println("location.replace('" + userService.createLoginURL("/") + "');");
		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Logger logger = Logger.getLogger("de.jtserver");
		logger.warning("POST!");
		logger.log(Level.FINE, "doPost");

		UserService userService = UserServiceFactory.getUserService();
		boolean isDevelopment = (SystemProperty.environment.value() == SystemProperty.Environment.Value.Development);

		if (req.getUserPrincipal() != null || isDevelopment) {
			String owner = null;
			if (isDevelopment) {
				owner = "ich";
			} else {
				owner = req.getUserPrincipal().getName();
			}

			String uriEncodedContent = req.getParameter("content");
			String x = URLDecoder.decode(uriEncodedContent, "UTF-8");
			String commandString = uriEncodedContent.substring(0, uriEncodedContent.indexOf("!"));
			String contentString = uriEncodedContent.substring(commandString.length() + 1);

			/**
			 * persist the current client-site "state" to the db
			 */
			if (commandString.equalsIgnoreCase("save_jtalk")) {

				JTalkDAO dao = new JTalkDAO();

				JTalkScript jts = null;
				List l = dao.findByOwner(owner);

				if (l == null || l.size() == 0) {
					jts = new JTalkScript();
					jts.setOwner(owner);
				} else {
					jts = (JTalkScript) l.get(0);
				}

				// read the head-part from the filesystem
				String head = JScriptHelper.readFile("js/head.js");

				jts.setScript(head + contentString);
				System.out.println("content: " + contentString.substring(contentString.length() - 100));
				dao.save(jts);

				callBackend(owner, "reset", "");
				
				resp.setContentType("application/x-javascript");
				resp.getWriter().println("alert('JTalk was saved.');");
			}
			/**
			 * reset the state to the jtalk.js, which is located in the
			 * filesystem ('js/jtalk.js')
			 */
			if (commandString.equalsIgnoreCase("reset")) {
				JTalkDAO dao = new JTalkDAO();
				List l = dao.findByOwner(owner);
				JTalkScript jts = null;
				if (l == null || l.size() == 0) {
					jts = new JTalkScript();
					jts.setOwner(owner);
				} else {
					jts = (JTalkScript) l.get(0);
				}

				String script = JScriptHelper.readFile("js/jtalk.js");
				jts.setScript(script);
				dao.save(jts);

				callBackend(owner, "reset", "");
				
				resp.setContentType("application/x-javascript");
				resp.getWriter().println("alert('JTalk was resetted, please refresh page!');");
			}
			if (commandString.equalsIgnoreCase("server")) {
				logger.warning("executing script on server");
								
				String resultString = callBackend(owner, commandString, contentString);

				resp.setContentType("application/x-javascript");
				resp.getWriter().println(resultString);

			}
		} else {
			resp.setContentType("application/x-javascript");
			resp.getWriter().println("location.replace('" + userService.createLoginURL("/") + "');");
		}

	}

	private String callBackend(String owner, String commandString, String contentString) throws MalformedURLException,
			IOException {
		BackendService backendsApi = BackendServiceFactory.getBackendService();
		String rhinoscopeURL = "http://" + backendsApi.getBackendAddress("rhinoscope", 0) + "/jtalk_backend";
		System.out.println(("rhinoscopeURL: " + rhinoscopeURL));

		URLFetchService fetchService = URLFetchServiceFactory.getURLFetchService();
		HTTPRequest requestToBackend = new HTTPRequest(new URL(rhinoscopeURL), HTTPMethod.POST);
		requestToBackend.setPayload(("contentString=" + contentString + "&owner=" + owner + "&commandString="+commandString).getBytes()); 

		HTTPResponse responseFromBackend = fetchService.fetch(requestToBackend);
		byte[] respContent = responseFromBackend.getContent();

		String resultString = new String(respContent);
		System.out.println("respContent:" + resultString);
		return resultString;
	}

}
